package com.yanlin.apipassenger.service;

import com.yanlin.apipassenger.remote.ServicePassengerUserClient;
import com.yanlin.apipassenger.remote.ServiceVerificationCodeClient;
import com.yanlin.internalcommon.constant.IdentityConstant;
import com.yanlin.internalcommon.dto.ResponseResult;
import com.yanlin.internalcommon.request.VerificationCodeDTO;
import com.yanlin.internalcommon.response.NumberCodeResponse;
import com.yanlin.internalcommon.response.TokenResponse;
import com.yanlin.internalcommon.util.JwtUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

import static com.yanlin.internalcommon.constant.CommonStatusEnum.VERIFICATION_CODE_ERROR;
import static com.yanlin.internalcommon.constant.IdentityConstant.PASSENGER_PHONE;
import static com.yanlin.internalcommon.constant.TokenConstant.ACCESS_TOKEN_TYPE;
import static com.yanlin.internalcommon.constant.TokenConstant.REFRESH_TOKEN_TYPE;
import static java.util.concurrent.TimeUnit.DAYS;

/**
 * <p>标题：VerificationService</p>
 * <p>功能：</p>
 * <p>
 * 其他说明：
 * </p>
 * <p>审核：</p>
 * <p>重构：</p>
 * <p>创建日期：2025-06-04 17:10</p>
 *
 * @author yanlin
 */
@Service
public class VerificationService extends com.yanlin.internalcommon.util.RedisPrefixUtil {

    @Autowired
    private ServiceVerificationCodeClient serviceVerificationCodeClient;
    @Autowired
    private ServicePassengerUserClient servicePassengerUserClient;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 生成验证码
     * @param passengerPhone 手机号
     * @return
     */
    public ResponseResult generateCode(String passengerPhone){

        //调用验证码服务
        System.out.println("调用验证码服务");
        ResponseResult<NumberCodeResponse> numberCodeResponse =
                serviceVerificationCodeClient.getNumberCode(6);
        int numberCode = numberCodeResponse.getData().getNumberCode();
        System.out.println("remote numberCode = " + numberCode);

        //存入redis:key、value、过期时间ttl
        String verificationCodeKey = getVerificationCodeKey(passengerPhone, PASSENGER_PHONE);
        stringRedisTemplate.opsForValue().set(
                verificationCodeKey,
                String.valueOf(numberCode),
                VERIFICATION_CODE_EXPIRATION,
                TimeUnit.MINUTES);

        //返回值
        return ResponseResult.success(numberCode);
    }

    /**
     * 校验验证码
     * @param passengerPhone 手机号
     * @param verificationCode 验证码
     * @return
     */
    public ResponseResult checkCode(String passengerPhone, String verificationCode) {
        // 根据手机号，去redis读取验证码
        String verificationCodeKey = getVerificationCodeKey(passengerPhone, PASSENGER_PHONE);
        String redisCode = stringRedisTemplate.opsForValue().get(verificationCodeKey);

        // 校验验证码
        if (StringUtils.isBlank(redisCode) || !verificationCode.equals(redisCode)) {
            return ResponseResult.fail(
                    VERIFICATION_CODE_ERROR.getCode(),
                    VERIFICATION_CODE_ERROR.getValue());

        }

        // 判断是否原来的用户，并进行业务处理
        VerificationCodeDTO verificationCodeDTO = new VerificationCodeDTO();
        verificationCodeDTO.setPassengerPhone(passengerPhone);
        servicePassengerUserClient.loginOrRegister(verificationCodeDTO);

        // 颁发令牌
        String accessToken = JwtUtils.generateToken(passengerPhone, PASSENGER_PHONE, ACCESS_TOKEN_TYPE);
        String refreshToken = JwtUtils.generateToken(passengerPhone, PASSENGER_PHONE, REFRESH_TOKEN_TYPE);
        // 令牌存放在redis中
        String accessTokenKey = getTokenKey(passengerPhone, PASSENGER_PHONE, ACCESS_TOKEN_TYPE);
        String refreshTokenKey = getTokenKey(passengerPhone, PASSENGER_PHONE, REFRESH_TOKEN_TYPE);
        stringRedisTemplate.opsForValue().set(accessTokenKey, accessToken, ACCESS_TOKEN_EXPIRATINO, DAYS);
        stringRedisTemplate.opsForValue().set(refreshTokenKey, refreshToken, REFRESH_TOKEN_EXPIRATINO, DAYS);
        /*stringRedisTemplate.opsForValue().set(accessTokenKey, accessToken, 30, TimeUnit.SECONDS);
        stringRedisTemplate.opsForValue().set(refreshTokenKey, refreshToken, 120, TimeUnit.SECONDS);*/

        TokenResponse tokenResponse = new TokenResponse();
        tokenResponse.setAccessToken(accessToken);
        tokenResponse.setRefreshToken(refreshToken);
        return ResponseResult.success(tokenResponse);
    }
}